<!--
 * @Description: 角色管理-新增|编辑 弹窗
 * @Version: 1.0
 * @Author: yxx
 * @Date: 2023-09-25 15:31:11
 * @LastEditors: yxx
 * @LastEditTime: 2024-12-09 16:35:26
-->
<template>
  <div class="add-role-dialog">
    <el-dialog v-model="isDialog" :title="title" width="400px" :close-on-click-modal="false">
      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="100px">
        <el-form-item prop="name" label="角色名称：">
          <el-input class="form-width" placeholder="角色名称" v-model="ruleForm.name"></el-input>
        </el-form-item>
        <el-form-item prop="status" label="角色状态：">
          <el-select v-model="ruleForm.status" placeholder="角色状态" clearable>
            <el-option label="正常" :value="1"></el-option>
            <el-option label="停用" :value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="menuIds" label="菜单权限：">
          <el-tree
            v-if="isDialog"
            ref="treeRef"
            :data="menuTree"
            node-key="id"
            show-checkbox
            :check-strictly="true"
            default-expand-all
            :props="typeProps"
            :expand-on-click-node="false"
          >
          </el-tree>
        </el-form-item>
        <el-form-item prop="remark" label="备注：">
          <el-input type="textarea" class="form-width" placeholder="备注" v-model="ruleForm.remark"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleCancel">取 消</el-button>
          <el-button type="primary" @click="handleConfirm(ruleFormRef)">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from "vue"
import { ElMessage, ElTree } from "element-plus"
import type { ElForm, FormInstance } from "element-plus"
import { getMenuTreeApi, getRoleMenuIdsApi, addRoleApi } from "@/api/modules/system"
import { SysRes } from "@/api/interface/system/response"
import { SysReq } from "@/api/interface/system/request"

const emit = defineEmits(["refreshData"])

const title = ref<string>("新增")
const isDialog = ref<boolean>(false)
const typeProps = {
  children: "children",
  label: "name",
  value: "id"
}
const menuTree = ref<SysRes.MenuTree[]>([])
const treeRef = ref<InstanceType<typeof ElTree>>()
const ruleForm = ref<SysReq.RoleAdd>({
  name: "",
  status: 1,
  remark: "",
  menuIds: [],
  deptIds: []
})
const ruleFormRef = ref<FormInstance>()
const rules = {
  name: [{ required: true, message: "必填项", trigger: "blur" }],
  status: [{ required: true, message: "必填项", trigger: "change" }]
}

/** 获取 所有菜单树 */
const getMenuList = () => {
  getMenuTreeApi().then(res => {
    menuTree.value = res.data
  })
}
getMenuList()
/** 获取 角色菜单树 */
const getRoleMenuIds = (id: number) => {
  getRoleMenuIdsApi({ id }).then(res => {
    treeRef.value?.setCheckedKeys(res.data)
  })
}
/** 重置 表单 */
const resetForm = () => {
  ruleFormRef.value?.resetFields()
  ruleForm.value = {
    name: "",
    status: 1,
    remark: "",
    menuIds: [],
    deptIds: []
  }
}
/** 弹窗 打开 */
const handleOpen = (str: string, row?: SysRes.RolePageList) => {
  isDialog.value = true
  title.value = str + "角色"
  if (row) {
    ruleForm.value = {
      id: row.id,
      name: row.name,
      status: row.status,
      remark: row.remark,
      menuIds: row.menuIds,
      deptIds: row.deptIds
    }
    nextTick(() => {
      getRoleMenuIds(row.id)
    })
  }
}
/** 弹窗 确定 */
const handleConfirm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(async valid => {
    if (!valid) return
    if (treeRef.value?.getHalfCheckedKeys()) {
      ruleForm.value.menuIds = [...treeRef.value?.getHalfCheckedKeys(), ...treeRef.value?.getCheckedKeys()] as number[]
    }
    await addRoleApi({ ...ruleForm.value })
    ElMessage.success("修改成功")
    isDialog.value = false
    emit("refreshData")
  })
}
/** 弹窗 取消 */
const handleCancel = () => {
  resetForm()
  isDialog.value = false
}

defineExpose({ handleOpen })
</script>

<style scoped lang="scss"></style>
